home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
boot
/
czesc_2
/
wbstartup
/
wbs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-25
|
36KB
|
1,146 lines
/*
* WBStartup - A (small) WBStartup manager
* Written by Stephan 'Septh' Schreiber
* Freeware - use at will
*
* There's still a lot of work to do,
* but I'm already quite happy with this.
*
* (BTW: set your tabs to 4 spaces)
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <exec/types.h>
#include <exec/lists.h>
#include <exec/nodes.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/exall.h>
#include <dos/notify.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <graphics/gfxmacros.h>
#include <libraries/gadtools.h>
#include <workbench/workbench.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/utility_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/icon_protos.h>
#include <clib/wb_protos.h>
#include <pragmas/exec_sysbase_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/gadtools_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/icon_pragmas.h>
#include <pragmas/wb_pragmas.h>
#define DEBUG 1
#include <debug.h>
/*****************************************************************************
* Macros & constants
*****************************************************************************/
/* Our default drawers */
#define ENABLED_DIR "Sys:WBStartup/WBStartup (Enabled)"
#define DISABLED_DIR "Sys:WBStartup/WBStartup (Disabled)"
/* Gadgets IDs */
enum
{ GAD_ENABLED_LV,
GAD_DISABLED_LV,
GAD_DISABLE_BUTTON,
GAD_ENABLE_BUTTON,
GAD_INFO_BUTTON,
GAD_START_BUTTON,
GAD_QUIT_BUTTON,
};
/* Type des tris */
enum
{ SORT_BY_PRIORITY,
SORT_BY_NAME,
};
/*****************************************************************************
* Structures & types
*****************************************************************************/
struct StartupTool
{ struct Node Node;
UBYTE Selected;
UBYTE StartPri;
UBYTE Name[40];
};
#define STF_SELECTED (1L<<0)
/*****************************************************************************
* Global variables
*****************************************************************************/
const UBYTE *version = "$VER: WBStartup 1.2 (25.11.95)";
extern struct Library *SysBase;
extern struct Library *DOSBase;
extern struct WBStartup *_WBenchMsg;
struct Library *UtilityBase;
struct Library *IntuitionBase;
struct Library *GadToolsBase;
struct Library *GfxBase;
struct Library *WorkbenchBase;
struct Library *IconBase;
struct Screen *scr;
struct DrawInfo *dri;
APTR vi;
struct Gadget *glist;
struct Gadget *enabled_lv;
struct Gadget *enabled_str;
struct Gadget *disabled_lv;
struct Gadget *disabled_str;
struct Gadget *disable_button;
struct Gadget *enable_button;
struct Gadget *info_button;
struct Gadget *start_button;
struct Hook lv_hook;
struct Window *win;
struct Requester req;
struct MinList enabled_list;
LONG num_enabled;
struct MinList disabled_list;
LONG num_disabled;
LONG sort_type;
LONG no_icon_position;
struct TextAttr topaz8 = { "topaz.font", 8, 0, 0 };
UBYTE enabled_buf[64];
UBYTE disabled_buf[64];
UBYTE enabled_dir[256];
UBYTE disabled_dir[256];
UBYTE win_title[128];
/*****************************************************************************
* Protoypes
*****************************************************************************/
extern void NewList(struct List *list);
/*****************************************************************************
* Bloque la fenêtre
*****************************************************************************/
VOID LockWindow(VOID)
{
InitRequester(&req);
Request(&req, win);
SetWindowPointer(win, WA_BusyPointer, TRUE,
WA_PointerDelay, TRUE,
TAG_DONE);
}
/*****************************************************************************
* Débloque la fenêtre
*****************************************************************************/
VOID UnlockWindow(VOID)
{
EndRequest(&req, win);
SetWindowPointerA(win, NULL);
}
/*****************************************************************************
* Show up an EasyRequester
*****************************************************************************/
LONG ShowReq(UBYTE *text, UBYTE *gadgets, ...)
{
static struct EasyStruct es =
{ sizeof(struct EasyStruct), 0L,
"WBStartup", NULL, NULL,
};
va_list va;
LONG ret;
/* Bloque la fenêtre */
LockWindow();
/* Affiche le Requester */
va_start(va, gadgets);
es.es_TextFormat = text;
es.es_GadgetFormat = gadgets;
ret = EasyRequestArgs(win, &es, NULL, (APTR)va);
va_end(va);
/* Débloque la fenêtre */
UnlockWindow();
return(ret);
}
/*****************************************************************************
* Insert a node in a list, in alphabetic order
*****************************************************************************/
void AddToolNode(struct List *list, struct Node *node)
{
struct Node *n;
/* Simple security */
node->ln_Succ = NULL;
node->ln_Pred = NULL;
switch(sort_type)
{ case SORT_BY_PRIORITY:
Enqueue(list, node);
break;
case SORT_BY_NAME:
/* Go backwards to the preceeding node */
n = list->lh_TailPred;
while (n->ln_Pred && (stricmp(n->ln_Name, node->ln_Name) >= 0))
n = n->ln_Pred;
/* Insert the new node after its predecessor */
Insert(list, node, n);
break;
}
}
/*****************************************************************************
* Look for a node, given its ordinal number
*****************************************************************************/
LONG GetNodeNumber(struct List *list, struct Node *node)
{
register struct Node *n;
LONG number = - 1;
n = list->lh_Head;
if (n->ln_Succ)
{ do
{ number++;
if (n == node)
break;
} while (n = n->ln_Succ);
}
return(number);
}
/*****************************************************************************
* Search the Nth node of a list
*****************************************************************************/
struct Node *GetNode(struct List *list, UWORD number)
{
register struct Node *n;
for (n = list->lh_Head; n->ln_Succ && number ; n = n->ln_Succ, number--)
{ /* Nothing */ }
return(number ? NULL : n);
}
/*****************************************************************************
* Edit a tool's icon
*****************************************************************************/
VOID EditToolInfo(struct StartupTool *st)
{
struct List *list;
BPTR lock, olddir;
struct NotifyRequest *nr;
LONG signum;
ULONG sig;
UBYTE icon_name[128];
BOOL changed = FALSE;
/* Bloque la fenêtre */
LockWindow();
list = (struct List *)&enabled_list;
if (FindName(list, st->Node.ln_Name))
lock = Lock(enabled_dir, SHARED_LOCK);
else
{ list = (struct List *)&disabled_list;
if (FindName(list, st->Node.ln_Name))
lock = Lock(disabled_dir, SHARED_LOCK);
else
lock = NULL;
}
if (lock)
{ olddir = CurrentDir(lock);
if (nr = AllocVec(sizeof(struct NotifyRequest), MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR))
{ if ((signum = AllocSignal(-1L)) != -1L)
{ sprintf(icon_name, "%s.info", st->Node.ln_Name);
nr->nr_Name = icon_name;
nr->nr_Flags = NRF_SEND_SIGNAL;
nr->nr_stuff.nr_Signal.nr_Task = FindTask(NULL);
nr->nr_stuff.nr_Signal.nr_SignalNum = signum;
if (StartNotify(nr))
{ WBInfo(lock, st->Node.ln_Name, win->WScreen);
sig = 1L << signum;
if (CheckSignal(sig) & sig)
changed = TRUE;
EndNotify(nr);
}
FreeSignal(signum);
}
FreeVec(nr);
}
/* Changé ? */
if (changed)
{ struct DiskObject *dobj;
UBYTE *s;
LONG pri;
struct Gadget *lv;
LONG num;
if (dobj = GetDiskObject(st->Node.ln_Name))
{ if (s = FindToolType(dobj->do_ToolTypes, "STARTPRI"))
StrToLong(s, &pri);
else
pri = 0;
if (pri != st->Node.ln_Pri)
{ lv = ((list == (struct List *)&enabled_list) ? enabled_lv : disabled_lv);
GT_SetGadgetAttrs(lv, win, NULL, GTLV_Labels, -1L, TAG_DONE);
Remove((struct Node *)st);
st->Node.ln_Pri = pri;
AddToolNode(list, (struct Node *)st);
num = GetNodeNumber(list, (struct Node *)st);
GT_SetGadgetAttrs(lv, win, NULL, GTLV_Labels, list,
GTLV_Selected, num,
GTLV_MakeVisible, num,
TAG_DONE);
}
FreeDiskObject(dobj);
}
}
CurrentDir(olddir);
UnLock(lock);
}
/* Débloque la fenêtre */
UnlockWindow();
}
/*****************************************************************************
* Move a file and its icon
*****************************************************************************/
BOOL MoveTool(struct StartupTool *st, UBYTE *from_dir, UBYTE *to_dir)
{
BPTR from_lock, to_lock;
UBYTE from_name[256], to_name[256], cmd[1024];
struct DiskObject *dobj;
BOOL ok = FALSE;
if (st)
{ if (from_lock = Lock(from_dir, SHARED_LOCK))
{ if (to_lock = Lock(to_dir, SHARED_LOCK))
{ /* Build source name */
strcpy(from_name, from_dir);
AddPart(from_name, st->Node.ln_Name, sizeof(from_name));
/* Build destination name */
strcpy(to_name, to_dir);
AddPart(to_name, st->Node.ln_Name, sizeof(to_name));
/* Are both file on the save volume? */
switch (SameLock(from_lock, to_lock))
{ case LOCK_SAME:
/* !?! */
break;
case LOCK_SAME_VOLUME:
/* Rename SOURCE as DEST */
Rename(from_name, to_name);
/* Also move the icon */
if (dobj = GetDiskObject(from_name))
{ DeleteDiskObject(from_name);
if (no_icon_position)
dobj->do_CurrentX = dobj->do_CurrentY = NO_ICON_POSITION;
PutDiskObject(to_name, dobj);
FreeDiskObject(dobj);
/* Done */
ok = TRUE;
}
else ShowReq("Can't write icon for\n'%s'\nDos Error %ld", to_name, IoErr());
break;
case LOCK_DIFFERENT:
/* Copy SOURCE to DEST */
sprintf(cmd, "c:copy <>NIL: FROM %s TO %s CLONE NOREQ", from_name, to_name);
SystemTagList(cmd, NULL);
/* Delete the original source file */
DeleteFile(from_name);
/* Also move the icon */
if (dobj = GetDiskObject(from_name))
{ DeleteDiskObject(from_name);
if (no_icon_position)
dobj->do_CurrentX = dobj->do_CurrentY = NO_ICON_POSITION;
PutDiskObject(to_name, dobj);
FreeDiskObject(dobj);
/* Done */
ok = TRUE;
}
else ShowReq("Can't write icon for\n'%s'\nDos Error %ld", to_name, IoErr());
break;
}
UnLock(to_lock);
}
UnLock(from_lock);
}
}
return(ok);
}
/*****************************************************************************
* Disable a tool (ie. move it from enabled_dir to disabled_dir)
*****************************************************************************/
VOID DisableTool(struct StartupTool *st)
{
/* First move the executable and its icon */
if (MoveTool(st, enabled_dir, disabled_dir))
{ GT_SetGadgetAttrs(enabled_lv, win, NULL, GTLV_Labels, ~0L, TAG_DONE);
GT_SetGadgetAttrs(disabled_lv, win, NULL, GTLV_Labels, ~0L, TAG_DONE);
/* Remove the tool from its list */
Remove((struct Node *)st);
num_enabled--;
/* And put it in the other list */
AddToolNode((struct List *)&disabled_list, (struct Node *)st);
num_disabled++;
/* Update the gadgets */
sprintf(enabled_buf, "%ld enabled items", num_enabled);
sprintf(disabled_buf, "%ld disabled items", num_disabled);
GT_SetGadgetAttrs(enabled_lv, win, NULL, GTLV_Labels, &enabled_list,
GTLV_Selected, ~0L,
TAG_DONE);
GT_SetGadgetAttrs(disabled_lv, win, NULL, GTLV_Labels, &disabled_list,
GTLV_Selected, ~0L,
GTLV_MakeVisible, GetNodeNumber((struct List *)&disabled_list, (struct Node *)st),
TAG_DONE);
GT_SetGadgetAttrs(enabled_str, win, NULL, GTTX_Text, &enabled_buf[0], TAG_DONE);
GT_SetGadgetAttrs(disabled_str, win, NULL, GTTX_Text, &disabled_buf[0], TAG_DONE);
GT_SetGadgetAttrs(enable_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
GT_SetGadgetAttrs(disable_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
GT_SetGadgetAttrs(info_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
//GT_SetGadgetAttrs(start_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
}
}
/*****************************************************************************
* Enable a tool (ie. move it from disabled_dir to enabled_dir)
*****************************************************************************/
VOID EnableTool(struct StartupTool *st)
{
if (MoveTool(st, disabled_dir, enabled_dir))
{ GT_SetGadgetAttrs(enabled_lv, win, NULL, GTLV_Labels, ~0L, TAG_DONE);
GT_SetGadgetAttrs(disabled_lv, win, NULL, GTLV_Labels, ~0L, TAG_DONE);
/* Remove the tool from its list */
Remove((struct Node *)st);
num_disabled--;
/* And put it in the other list */
AddToolNode((struct List *)&enabled_list, (struct Node *)st);
num_enabled++;
/* Update the gadgets */
sprintf(enabled_buf, "%ld enabled items", num_enabled);
sprintf(disabled_buf, "%ld disabled items", num_disabled);
GT_SetGadgetAttrs(enabled_lv, win, NULL, GTLV_Labels, &enabled_list,
GTLV_Selected, ~0L,
GTLV_MakeVisible, GetNodeNumber((struct List *)&enabled_list, (struct Node *)st),
TAG_DONE);
GT_SetGadgetAttrs(disabled_lv, win, NULL, GTLV_Labels, &disabled_list,
GTLV_Selected, ~0L,
TAG_DONE);
GT_SetGadgetAttrs(enabled_str, win, NULL, GTTX_Text, &enabled_buf[0], TAG_DONE);
GT_SetGadgetAttrs(disabled_str, win, NULL, GTTX_Text, &disabled_buf[0], TAG_DONE);
GT_SetGadgetAttrs(enable_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
GT_SetGadgetAttrs(disable_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
GT_SetGadgetAttrs(info_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
//GT_SetGadgetAttrs(start_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
}
}
/*****************************************************************************
* Main event loop
*****************************************************************************/
VOID MainLoop(VOID)
{
UWORD esel, dsel;
ULONG secs, mics;
struct StartupTool *st;
BOOL fini;
struct IntuiMessage *imsg, im;
esel = (UWORD)~0;
dsel = (UWORD)~0;
secs = 0L;
mics = 0L;
st = NULL;
fini = FALSE;
do
{ WaitPort(win->UserPort);
while (imsg = GT_GetIMsg(win->UserPort))
{ im = *imsg;
GT_ReplyIMsg(imsg);
imsg = &im;
switch(imsg->Class)
{ case IDCMP_CLOSEWINDOW:
fini = TRUE;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(win);
GT_EndRefresh(win, TRUE);
break;
case IDCMP_VANILLAKEY:
if (imsg->Code == 27)
fini = TRUE;
break;
case IDCMP_GADGETUP:
switch(((struct Gadget *)imsg->IAddress)->GadgetID)
{ case GAD_ENABLED_LV:
if ((esel == imsg->Code) && DoubleClick(secs, mics, imsg->Seconds, imsg->Micros))
{ /* Edit tooltypes on double-click */
EditToolInfo(st);
esel = GetNodeNumber((struct List *)&enabled_list, (struct Node *)st);
}
else
{ esel = imsg->Code;
dsel = (UWORD)~0;
secs = imsg->Seconds;
mics = imsg->Micros;
st = (struct StartupTool *)GetNode((struct List *)&enabled_list, esel);
/* Update the gadgets */
GT_SetGadgetAttrs(disabled_lv, win, NULL, GTLV_Selected, ~0, TAG_DONE);
GT_SetGadgetAttrs(enable_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
GT_SetGadgetAttrs(disable_button, win, NULL, GA_Disabled, FALSE, TAG_DONE);
GT_SetGadgetAttrs(info_button, win, NULL, GA_Disabled, FALSE, TAG_DONE);
//GT_SetGadgetAttrs(start_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
}
break;
case GAD_DISABLED_LV:
if ((dsel == imsg->Code) && DoubleClick(secs, mics, imsg->Seconds, imsg->Micros))
{ /* Edit tooltypes on double-click -- not implemented */
EditToolInfo(st);
dsel = GetNodeNumber((struct List *)&disabled_list, (struct Node *)st);
}
else
{ esel = (UWORD)~0;
dsel = imsg->Code;
secs = imsg->Seconds;
mics = imsg->Micros;
st = (struct StartupTool *)GetNode((struct List *)&disabled_list, dsel);
/* Update the gadgets */
GT_SetGadgetAttrs(enabled_lv, win, NULL, GTLV_Selected, ~0, TAG_DONE);
GT_SetGadgetAttrs(enable_button, win, NULL, GA_Disabled, FALSE, TAG_DONE);
GT_SetGadgetAttrs(disable_button, win, NULL, GA_Disabled, TRUE, TAG_DONE);
GT_SetGadgetAttrs(info_button, win, NULL, GA_Disabled, FALSE, TAG_DONE);
//GT_SetGadgetAttrs(start_button, win, NULL, GA_Disabled, FALSE, TAG_DONE);
}
break;
case GAD_DISABLE_BUTTON:
DisableTool(st);
st = NULL;
break;
case GAD_ENABLE_BUTTON:
EnableTool(st);
st = NULL;
break;
case GAD_START_BUTTON:
/* Start the tool -- not implemented */
break;
case GAD_INFO_BUTTON:
/* Edit the tool's icon */
EditToolInfo(st);
if (esel != (UWORD)~0)
esel = GetNodeNumber((struct List *)&enabled_list, (struct Node *)st);
else
dsel = GetNodeNumber((struct List *)&disabled_list, (struct Node *)st);
break;
case GAD_QUIT_BUTTON:
fini = TRUE;
break;
}
break;
}
}
} while (!fini);
}
/*****************************************************************************
* The GTLV_CallBack hook
*****************************************************************************/
ULONG __asm __saveds GTLVCallBack(register __a0 struct Hook *hook,
register __a2 struct StartupTool *st,
register __a1 struct LVDrawMsg *lvdmsg)
{
static UWORD ghost_pattern[] = { 0x4444, 0x1111 };
UBYTE pri[10];
LONG apen, bpen, pl, pw, w, h, dy, len;
struct TextExtent te;
if (lvdmsg->lvdm_MethodID == LV_DRAW)
{ switch(lvdmsg->lvdm_State)
{ case LVR_NORMAL:
case LVR_NORMALDISABLED:
apen = lvdmsg->lvdm_DrawInfo->dri_Pens[TEXTPEN];
bpen = lvdmsg->lvdm_DrawInfo->dri_Pens[BACKGROUNDPEN];
break;
case LVR_SELECTED:
case LVR_SELECTEDDISABLED:
apen = lvdmsg->lvdm_DrawInfo->dri_Pens[FILLTEXTPEN];
bpen = lvdmsg->lvdm_DrawInfo->dri_Pens[FILLPEN];
break;
}
/* Efface le fond */
SetAPen(lvdmsg->lvdm_RastPort, bpen);
RectFill(lvdmsg->lvdm_RastPort, lvdmsg->lvdm_Bounds.MinX, lvdmsg->lvdm_Bounds.MinY,
lvdmsg->lvdm_Bounds.MaxX, lvdmsg->lvdm_Bounds.MaxY);
/* Calcule la largeur de la priorité */
pl = sprintf(pri, "%ld", st->Node.ln_Pri);
pw = TextLength(lvdmsg->lvdm_RastPort, pri, pl);
/* Calcule la largeur de la ligne */
w = (UWORD)((lvdmsg->lvdm_Bounds.MaxX - lvdmsg->lvdm_Bounds.MinX + 1) - pw - 8);
/* Calcule la hauteur totale de la ligne */
h = (UWORD)(lvdmsg->lvdm_Bounds.MaxY - lvdmsg->lvdm_Bounds.MinY + 1);
/* Centre la ligne verticalement */
dy = (UWORD)(((h - lvdmsg->lvdm_RastPort->Font->tf_YSize) / 2) + lvdmsg->lvdm_RastPort->Font->tf_Baseline);
/* Trouve le nombre maximum de caractères à dessiner */
len = TextFit(lvdmsg->lvdm_RastPort, st->Node.ln_Name, strlen(st->Node.ln_Name), &te, NULL, 1L, w, h);
/* Dessine le texte */
SetAPen(lvdmsg->lvdm_RastPort, apen);
SetDrMd(lvdmsg->lvdm_RastPort, JAM1);
Move(lvdmsg->lvdm_RastPort, lvdmsg->lvdm_Bounds.MinX + 4, lvdmsg->lvdm_Bounds.MinY + dy);
Text(lvdmsg->lvdm_RastPort, st->Node.ln_Name, len);
/* Dessine le texte de la priorité */
Move(lvdmsg->lvdm_RastPort, lvdmsg->lvdm_Bounds.MaxX - pw - 4, lvdmsg->lvdm_Bounds.MinY + dy);
Text(lvdmsg->lvdm_RastPort, pri, pl);
/* Le gadget est inhibé? */
if ((lvdmsg->lvdm_State == LVR_NORMALDISABLED) || (lvdmsg->lvdm_State == LVR_SELECTEDDISABLED))
{ SetAPen(lvdmsg->lvdm_RastPort, lvdmsg->lvdm_DrawInfo->dri_Pens[BLOCKPEN]);
SetAfPt(lvdmsg->lvdm_RastPort, ghost_pattern, 1L);
RectFill(lvdmsg->lvdm_RastPort, lvdmsg->lvdm_Bounds.MinX, lvdmsg->lvdm_Bounds.MinY,
lvdmsg->lvdm_Bounds.MaxX, lvdmsg->lvdm_Bounds.MaxY);
SetAfPt(lvdmsg->lvdm_RastPort, NULL, 0);
}
return(LVCB_OK);
}
return(LVCB_UNKNOWN);
}
/*****************************************************************************
* Create the gadgets - no font sensitivity, use old good Topaz/8...
*****************************************************************************/
BOOL CreateGadgets(VOID)
{
struct NewGadget ng;
struct Gadget *g;
WORD ox, oy;
BOOL ok = FALSE;
glist = NULL;
if (g = CreateContext(&glist))
{ ox = scr->WBorLeft + 5;
oy = scr->BarHeight + 1 + 20;
lv_hook.h_Entry = (ULONG (*)())GTLVCallBack;
lv_hook.h_SubEntry = NULL;
lv_hook.h_Data = NULL;
/* ListView 'enabled' */
ng.ng_LeftEdge = ox;
ng.ng_TopEdge = oy;
ng.ng_Width = 250;
ng.ng_Height = 130;
ng.ng_GadgetText = "Enabled Tools";
ng.ng_TextAttr = &topaz8;
ng.ng_GadgetID = GAD_ENABLED_LV;
ng.ng_Flags = PLACETEXT_ABOVE|NG_HIGHLABEL;
ng.ng_VisualInfo = vi;
ng.ng_UserData = NULL;
g = enabled_lv = CreateGadget(LISTVIEW_KIND, g, &ng, GTLV_ShowSelected, NULL,
GTLV_CallBack, &lv_hook,
GT_Underscore, '_',
LAYOUTA_Spacing, 2L,
TAG_DONE);
ng.ng_TopEdge += 130;
ng.ng_Height = 14;
ng.ng_GadgetText = NULL;
g = enabled_str = CreateGadget(TEXT_KIND, g, &ng, GTTX_Border, TRUE,
TAG_DONE);
/* ListView 'disabled' */
ng.ng_LeftEdge += 360;
ng.ng_TopEdge = oy;
ng.ng_Height = 130;
ng.ng_GadgetText = "Disabled Tools";
ng.ng_GadgetID = GAD_DISABLED_LV;
g = disabled_lv = CreateGadget(LISTVIEW_KIND, g, &ng, GTLV_ShowSelected, NULL,
GTLV_CallBack, &lv_hook,
GT_Underscore, '_',
LAYOUTA_Spacing, 2L,
TAG_DONE);
ng.ng_TopEdge += 130;
ng.ng_Height = 14;
ng.ng_GadgetText = NULL;
g = disabled_str = CreateGadget(TEXT_KIND, g, &ng, GTTX_Border, TRUE,
TAG_DONE);
/* Bouton 'Disable ->' */
ng.ng_LeftEdge = ox + 260;
ng.ng_TopEdge = oy;
ng.ng_Width = 90;
ng.ng_Height = 14;
ng.ng_GadgetText = "_Disable ->";
ng.ng_GadgetID = GAD_DISABLE_BUTTON;
ng.ng_Flags = PLACETEXT_IN;
g = disable_button = CreateGadget(BUTTON_KIND, g, &ng, GT_Underscore, '_',
GA_Disabled, TRUE,
TAG_DONE);
/* Bouton '<- Enable' */
ng.ng_TopEdge += 20;
ng.ng_GadgetText = "<- _Enable";
ng.ng_GadgetID = GAD_ENABLE_BUTTON;
g = enable_button = CreateGadget(BUTTON_KIND, g, &ng, GT_Underscore, '_',
GA_Disabled, TRUE,
TAG_DONE);
/* Bouton 'Info...' */
ng.ng_TopEdge += 20;
ng.ng_GadgetText = "_Info...";
ng.ng_GadgetID = GAD_INFO_BUTTON;
g = info_button = CreateGadget(BUTTON_KIND, g, &ng, GT_Underscore, '_',
GA_Disabled, TRUE,
TAG_DONE);
/* Bouton 'Start' */
ng.ng_TopEdge += 20;
ng.ng_GadgetText = "_Start";
ng.ng_GadgetID = GAD_START_BUTTON;
g = start_button = CreateGadget(BUTTON_KIND, g, &ng, GT_Underscore, '_',
GA_Disabled, TRUE,
TAG_DONE);
/* Bouton 'Quit' */
ng.ng_TopEdge = oy + 130;
ng.ng_GadgetText = "_Quit";
ng.ng_GadgetID = GAD_QUIT_BUTTON;
g = CreateGadget(BUTTON_KIND, g, &ng, GT_Underscore, '_',
TAG_DONE);
/* Ok ? */
if (g)
ok = TRUE;
}
/* Retourne TRUE ou FALSE */
return(ok);
}
/*****************************************************************************
* Free a list of tools
*****************************************************************************/
VOID FreeTools(struct List *list)
{
struct StartupTool *st;
while (st = (struct StartupTool *)RemTail(list))
FreeVec(st);
}
/*****************************************************************************
* Scan a directory of tools
*****************************************************************************/
LONG ScanTools(UBYTE *path, struct List *list)
{
BPTR lock, olddir;
UBYTE pat[32];
struct ExAllControl *eac;
struct ExAllData *ead;
BOOL more;
UBYTE eadata[1024], name[128], *s;
struct DiskObject *dobj;
struct StartupTool *st;
LONG pri, num = -1;
sprintf(win_title, "Scanning '%s'...", path);
SetWindowTitles(win, win_title, (UBYTE *)-1L);
if ((lock = Lock(path, SHARED_LOCK)) == NULL)
{ if (IoErr() == ERROR_OBJECT_NOT_FOUND)
{ switch(ShowReq("Directory '%s'\ndoes not exist.\nDo you want to create it?", "Yes|No", path))
{ case 1: // Yes
if (lock = CreateDir(path))
{ /* Add an icon, the same as 'Sys:WBStartup' (if possible) */
if (dobj = GetDiskObjectNew("Sys:WBStartup"))
{ if (dobj->do_Type != WBDRAWER)
{ FreeDiskObject(dobj);
dobj = GetDefDiskObject(WBDRAWER);
}
if (dobj)
{ dobj->do_CurrentX = dobj->do_CurrentY = NO_ICON_POSITION;
PutDiskObject(path, dobj);
FreeDiskObject(dobj);
}
else ShowReq("Can't create icon for\n'%s'\n", "Continue", path);
}
else ShowReq("Can't create icon for\n'%s'\n", "Continue", path);
}
else ShowReq("Can't create directory\n'%s'\nDos Error %ld\n", "Cancel", path, IoErr());
break;
case 0: // No
break;
}
}
else ShowReq("Can't access directory\n'%s'\nDos Error %ld\n", "Cancel", path, IoErr());
}
if (lock)
{ olddir = CurrentDir(lock);
/* Parse our pattern */
ParsePatternNoCase("#?.info", pat, sizeof(pat));
if (eac = AllocDosObject(DOS_EXALLCONTROL, NULL))
{ eac->eac_LastKey = NULL;
eac->eac_MatchString = pat;
eac->eac_MatchFunc = NULL;
num = 0;
do
{ more = ExAll(lock, (struct ExAllData *)eadata, sizeof(eadata), ED_NAME, eac);
if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES))
{ /* Erreur */
break;
}
if (eac->eac_Entries == 0)
{ /* Fin normale, mais pas d'entrées */
continue;
}
/* Ajoute la ou les entrées */
ead = (struct ExAllData *)eadata;
do
{ /* Copie le nom, sans le '.info' */
s = stpcpy(name, ead->ed_Name); // stpcpy() retourne la FIN de la chaîne
s[-5] = '\0';
/* Lit l'icône */
if (dobj = GetDiskObject(name))
{ /* Est-ce un OUTIL ou un PROJET ? */
if ((dobj->do_Type == WBTOOL) || (dobj->do_Type == WBPROJECT))
{ /* Ajoute un noeud à la liste */
if (st = AllocVec(sizeof(struct StartupTool), MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR))
{ st->Node.ln_Name = &st->Name[0];
strcpy(st->Node.ln_Name, name);
/* Trouve la priorité */
if ((s = FindToolType(dobj->do_ToolTypes, "STARTPRI")) && StrToLong(s, &pri))
st->Node.ln_Pri = pri;
AddToolNode(list, (struct Node *)st);
num++;
}
}
FreeDiskObject(dobj);
}
/* Passe à l'entrée suivante */
ead = ead->ed_Next;
} while (ead);
} while (more);
FreeDosObject(DOS_EXALLCONTROL, eac);
}
CurrentDir(olddir);
UnLock(lock);
}
/* Return the number of tools read, or -1 on error */
return(num);
}
/*****************************************************************************
* Get the arguments
*****************************************************************************/
#define TEMPLATE "ENABLED_DIR/K,DISABLED_DIR/K,SORT/K,NO_ICON_POSITION/S"
enum
{ OPT_ENABLED_DIR,
OPT_DISABLED_DIR,
OPT_SORT,
OPT_NO_ICON_POSITION,
NUM_OPTS
};
BOOL GetArgs(VOID)
{
BOOL ok = TRUE;
/* Set the defaults */
strcpy(enabled_dir, ENABLED_DIR);
strcpy(disabled_dir, DISABLED_DIR);
sort_type = SORT_BY_PRIORITY;
no_icon_position = FALSE;
if (_WBenchMsg)
{ BPTR olddir;
struct DiskObject *dobj;
UBYTE *s;
olddir = CurrentDir(_WBenchMsg->sm_ArgList->wa_Lock);
/* Read our ToolTypes */
if (dobj = GetDiskObject(_WBenchMsg->sm_ArgList->wa_Name))
{ if (s = FindToolType(dobj->do_ToolTypes, "ENABLED_DIR"))
strcpy(enabled_dir, s);
if (s = FindToolType(dobj->do_ToolTypes, "DISABLED_DIR"))
strcpy(disabled_dir, s);
if (s = FindToolType(dobj->do_ToolTypes, "SORT"))
{ if (MatchToolValue(s, "PRIORITY"))
sort_type = SORT_BY_PRIORITY;
else if (MatchToolValue(s, "NAME"))
sort_type = SORT_BY_NAME;
}
if (s = FindToolType(dobj->do_ToolTypes, "NO_ICON_POSITION"))
no_icon_position = TRUE;
FreeDiskObject(dobj);
}
CurrentDir(olddir);
}
else
{ ULONG opts[NUM_OPTS];
struct RDArgs *rda;
memset(opts, 0, sizeof(opts));
rda = ReadArgs(TEMPLATE, opts, NULL);
/* Check for Ctrl-C break */
if (CheckSignal(SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
{ if (rda)
{ FreeArgs(rda);
rda = NULL;
}
SetIoErr(ERROR_BREAK);
ok = FALSE; // Tell caller to quit
}
if (rda)
{ if (opts[OPT_ENABLED_DIR])
strcpy(enabled_dir, (UBYTE *)opts[OPT_ENABLED_DIR]);
if (opts[OPT_DISABLED_DIR])
strcpy(disabled_dir, (UBYTE *)opts[OPT_DISABLED_DIR]);
if (opts[OPT_SORT])
{ if (stricmp((UBYTE *)opts[OPT_SORT], "PRIORITY"))
sort_type = SORT_BY_PRIORITY;
else if (stricmp((UBYTE *)opts[OPT_SORT], "NAME"))
sort_type = SORT_BY_NAME;
}
if (opts[OPT_NO_ICON_POSITION])
no_icon_position = TRUE;
FreeArgs(rda);
}
else PrintFault(IoErr(), NULL);
}
/* Return FALSE if Ctrl-C was hit during ReadArgs() */
return(ok);
}
/*****************************************************************************
* Program entry point
*****************************************************************************/
void main(void)
{
struct IBox zoom;
/* Open the used libraries */
if (UtilityBase = OpenLibrary("utility.library", 39L))
{ if (IntuitionBase = OpenLibrary("intuition.library", 39L))
{ if (GadToolsBase = OpenLibrary("gadtools.library", 39L))
{ if (GfxBase = OpenLibrary("graphics.library", 39L))
{ if (WorkbenchBase = OpenLibrary("workbench.library", 39L))
{ if (IconBase = OpenLibrary("icon.library", 39L))
{ /* Read the arguments, stop if Ctrl-C is hit */
if (GetArgs())
{ /* Open the window */
if ((scr = LockPubScreen("FRONTPUBSCREEN")) == NULL)
scr = LockPubScreen(NULL);
if (scr)
{ if (dri = GetScreenDrawInfo(scr))
{ if (vi = GetVisualInfoA(scr, NULL))
{ if (CreateGadgets())
{ /* Setup our alternate window position */
zoom.Left = -1;
zoom.Top = -1;
zoom.Width = 150;
zoom.Height = scr->BarHeight + 1;
if (win = OpenWindowTags(NULL, WA_Left, 0,
WA_Top, scr->BarHeight + 1,
WA_InnerWidth, 620L,
WA_InnerHeight, 169L,
WA_AutoAdjust, TRUE,
WA_MinWidth, zoom.Width,
WA_MinHeight, zoom.Height,
WA_Zoom, &zoom,
WA_Flags, WFLG_CLOSEGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET|
WFLG_SIMPLE_REFRESH|
WFLG_RMBTRAP|WFLG_NEWLOOKMENUS|WFLG_ACTIVATE,
WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
IDCMP_VANILLAKEY|
LISTVIEWIDCMP|BUTTONIDCMP,
WA_PubScreen, scr,
WA_Title, "WBStartup",
WA_ScreenTitle, "WBStartup - ©1995 by RingarSoft, Inc.",
WA_Gadgets, glist,
WA_BusyPointer, TRUE,
WA_PointerDelay, TRUE,
TAG_DONE))
{ GT_RefreshWindow(win, NULL);
/* Initialize our lists */
NewList((struct List *)&enabled_list);
NewList((struct List *)&disabled_list);
/* Scan both source and destination drawers */
if ((num_enabled = ScanTools(enabled_dir, (struct List *)&enabled_list)) >= 0)
{ if ((num_disabled = ScanTools(disabled_dir, (struct List *)&disabled_list)) >= 0)
{ /* Reset the window's title */
SetWindowTitles(win, "WBStartup", (UBYTE *)-1L);
/* Update the gadgets */
sprintf(enabled_buf, "%ld enabled tools", num_enabled);
sprintf(disabled_buf, "%ld disabled tools", num_disabled);
GT_SetGadgetAttrs(enabled_lv, win, NULL, GTLV_Labels, &enabled_list, TAG_DONE);
GT_SetGadgetAttrs(enabled_str, win, NULL, GTTX_Text, &enabled_buf[0], TAG_DONE);
GT_SetGadgetAttrs(disabled_lv, win, NULL, GTLV_Labels, &disabled_list, TAG_DONE);
GT_SetGadgetAttrs(disabled_str, win, NULL, GTTX_Text, &disabled_buf[0], TAG_DONE);
ClearPointer(win);
/* Handle events */
MainLoop();
}
}
/* Clear the gadgets */
GT_SetGadgetAttrs(enabled_lv, win, NULL, GTLV_Labels, ~0L, TAG_DONE);
GT_SetGadgetAttrs(disabled_lv, win, NULL, GTLV_Labels, ~0L, TAG_DONE);
/* Free the scanned lists of tools */
FreeTools((struct List *)&disabled_list);
FreeTools((struct List *)&enabled_list);
/* Close the window */
CloseWindow(win);
}
/* Free the gadgets */
FreeGadgets(glist);
}
FreeVisualInfo(vi);
}
FreeScreenDrawInfo(scr, dri);
}
UnlockPubScreen(NULL, scr);
}
}
/* Close the libraries */
CloseLibrary(IconBase);
}
CloseLibrary(WorkbenchBase);
}
CloseLibrary(GfxBase);
}
CloseLibrary(GadToolsBase);
}
CloseLibrary(IntuitionBase);
}
CloseLibrary(UtilityBase);
}
}